Mount the google drive¶


In [ ]:
from google.colab import drive
drive.mount('/content/drive')
Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).

Import the necessary Libraries¶


In [1]:
import numpy as np
import pandas as pd
import os
import cv2
import matplotlib.pyplot as plt
import pandas
import random
import skimage
import warnings
import csv
from skimage.feature import graycomatrix, graycoprops
from skimage.filters import threshold_otsu
from skimage.filters import threshold_otsu
from prettytable import PrettyTable
from sklearn.cluster import KMeans
from skimage.measure import shannon_entropy
from skimage import io, filters, feature
from sklearn.metrics import f1_score
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report

Gray Scale Conversion of all classes¶


In [2]:
test_dataset = '/content/drive/MyDrive/plant_data/Train_data'

cnt=0

# Loop through all image files in the directory
for filename in os.listdir(test_dataset):
    # Load the image and convert it to grayscale
    img = cv2.imread(os.path.join(test_dataset, filename))
    
    con_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    cnt = cnt+1

    if cnt<5:
      # Display the original and grayscale images
      plt.subplot(1, 2, 1)
      plt.imshow(img)
      plt.title('({})'.format(os.path.basename(filename)))
      plt.subplot(1, 2, 2)
      plt.imshow(con_img, cmap='gray')
      plt.title('Grayscale Image')
      plt.show()

Load the Dataset Path¶


In [9]:
# Set the path to the image dataset folder
dataset_path = "/content/drive/MyDrive/plant_data/Train_data"

K-means for segmentation¶


In [4]:
def apply_kmeans(image):
    # Reshape the image to a 2D array
    pixels = image.reshape(-1, 1)
    
    # Initialize KMeans with 3 clusters and fit the data
    kmeans = KMeans(n_clusters=3, random_state=42).fit(pixels)
    
    # Get the cluster labels and reshape them to the original image size
    labels = kmeans.labels_.reshape(image.shape)
    
    # Return the clustered image
    return labels

Otsu-Threshholding for segmentation¶


In [5]:
def apply_otsu(image) :
  # Find Otsu threshold and binarize the image
  thresh = threshold_otsu(image)
  bin_img = image < thresh
  return bin_img* 255,thresh

Applying all both segmentation techniques and comparing¶


In [6]:
import warnings
warnings.filterwarnings('ignore')

# Define the dimensions of the resized images
image_size = (256, 256)

# Loop over each image file in the dataset folder
for filename in os.listdir(dataset_path):
        # Load the image
        image = cv2.imread(os.path.join(dataset_path, filename))
        
        # Resize the image
        image = cv2.resize(image, image_size)
        
        # Convert the image to grayscale
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        
        # Apply Gaussian blur to reduce noise
        blurred = cv2.GaussianBlur(gray, (5, 5), 0)

        # Apply K-means clustering to the preprocessed image
        clustered_img = apply_kmeans(blurred)
        
        # Apply Otsu Thresh holding to the preprocessed image
        otsu_img,thresh = apply_otsu(gray)
        
        # Printing Some images
        print("Thresh hold for otsu Method is : " + str(thresh))
        print()
        fig, axs = plt.subplots(1, 4, figsize=(12, 4))

        label = '{}'.format(os.path.basename(filename))
        axs[0].imshow(image)
        axs[0].set_title(label)

        label = 'gray'
        axs[1].imshow(gray, cmap='gray')
        axs[1].set_title(label)

        label = 'Otsu'
        axs[2].imshow(otsu_img)
        axs[2].set_title(label)

        label = 'K-Means'
        axs[3].imshow(clustered_img)
        axs[3].set_title(label)

        plt.subplots_adjust(wspace=0.4)
        plt.show()
        print()
Thresh hold for otsu Method is : 174

Thresh hold for otsu Method is : 73

Thresh hold for otsu Method is : 111

Thresh hold for otsu Method is : 149


In [7]:
import os
import cv2
import shutil

dataset = '/content/drive/MyDrive/DATA_SET/'
Otsu_path = '/content/drive/MyDrive/plant_data/Preprocessed_otsu_dataset'
image_size = (256, 256)

# Loop over each image file in the dataset folder
for foldername in os.listdir(dataset):
    # Check if the current path is a directory
    if os.path.isdir(os.path.join(dataset, foldername)):
        # Create a new directory to save the Otsu images
        otsu_path = os.path.join(Otsu_path, f"{foldername}_otsu")
        os.makedirs(otsu_path, exist_ok=True)
        
        # Loop over each image file in the current directory
        for filename in os.listdir(os.path.join(dataset, foldername)):
            # Load the image
            image = cv2.imread(os.path.join(dataset, foldername, filename))
            
            # Resize the image
            image = cv2.resize(image, image_size)
            
            # Convert the image to grayscale
            gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
            
            # Apply Gaussian blur to reduce noise
            blurred = cv2.GaussianBlur(gray, (5, 5), 0)

            # Apply K-means clustering to the preprocessed image
            clustered_img = apply_kmeans(blurred)
            
            # Apply Otsu Thresh holding to the preprocessed image
            otsu_img,thresh = apply_otsu(gray)
            
            # Write the Otsu image to the corresponding new folder
            cv2.imwrite(os.path.join(otsu_path, filename), otsu_img)

GLCM Matrix for feature extraction¶


In [8]:
def GLCM(image) : 
    # Calculate GLCM for all angles
    glcms = []
    theta = [0, np.pi/4, np.pi/2, 3*np.pi/4]  # angles for GLCM
    theta1 = ["0","pi/4","pi/2","3*pi/4"]

    d = 1
    for angle in theta:
        glcm = graycomatrix(image, distances=[d], angles=[angle], levels=256, symmetric=True, normed=True)
        glcms.append(glcm)

    # Extract GLCM features
    headers = ["Angle", "Contrast", "Dissimilarity", "Homogeneity", "ASM", "Energy", "Correlation", "Entropy"]
    table = PrettyTable(headers)

    i=0

    for glcm in glcms:
        contrast = graycoprops(glcm, 'contrast')
        dissimilarity = graycoprops(glcm, 'dissimilarity')
        homogeneity = graycoprops(glcm, 'homogeneity')
        energy = graycoprops(glcm, 'energy')
        correlation = graycoprops(glcm, 'correlation')
        ASM = graycoprops(glcm, 'ASM')
        entropy = shannon_entropy(glcm)

        row = [theta1[i], contrast[0][0], dissimilarity[0][0], homogeneity[0][0], ASM[0][0], energy[0][0], correlation[0][0], entropy]
        table.add_row(row)
        i = i+1

    return table

Printing GLCM matrix (7 features) for all 4-Classes¶


In [10]:
import warnings
warnings.filterwarnings('ignore')

# Define the dimensions of the resized images
image_size = (256, 256)

# Loop over each image file in the dataset folder
for filename in os.listdir(dataset_path):
    print()
    print("GLCM Matrix for " + '{}'.format(os.path.basename(filename)))    
    print()
    # Load the image
    image = cv2.imread(os.path.join(dataset_path, filename))

    # Resize the image
    image = cv2.resize(image, image_size)

    # Convert the image to grayscale
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # Apply Gaussian blur to reduce noise
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)

    # Apply K-means clustering to the preprocessed image
    clustered_img = apply_kmeans(blurred)

    # Apply Otsu Thresh holding to the preprocessed image
    otsu_img, thresh = apply_otsu(gray)

    # Compute GLCM matrix for the preprocessed image
    print("GLCM Matrix for Preprocessed Image : ")
    print(GLCM(blurred))
    print()

    # Compute GLCM matrix for the Otsu-thresholded image
    print("GLCM Matrix for Otsu Thresh Holding Segmentation Image : ")
    print(GLCM(otsu_img))
    print()

    # Compute GLCM matrix for the K-means clustered image
    print("GLCM Matrix for K-Means Clustering Image : ")
    print(GLCM(clustered_img))
    print()

    # Display some images
    fig, axs = plt.subplots(1, 4, figsize=(12, 4))

    label = '{}'.format(os.path.basename(filename))
    axs[0].imshow(image)
    axs[0].set_title(label)

    label = 'gray'
    axs[1].imshow(blurred, cmap='gray')
    axs[1].set_title(label)

    label = 'Otsu'
    axs[2].imshow(otsu_img)
    axs[2].set_title(label)

    label = 'K-Means'
    axs[3].imshow(clustered_img)
    axs[3].set_title(label)

    plt.subplots_adjust(wspace=0.4)
    plt.show()
GLCM Matrix for Healthy.jpg

GLCM Matrix for Preprocessed Image : 
+--------+--------------------+--------------------+---------------------+-----------------------+---------------------+--------------------+--------------------+
| Angle  |      Contrast      |   Dissimilarity    |     Homogeneity     |          ASM          |        Energy       |    Correlation     |      Entropy       |
+--------+--------------------+--------------------+---------------------+-----------------------+---------------------+--------------------+--------------------+
|   0    | 13.36392463235294  | 2.338679534313725  |  0.4029695400697429 |  0.002900283267891256 | 0.05385427808346572 | 0.9865349701326883 | 0.5822016904788471 |
|  pi/4  | 14.641445597846982 | 2.5672279892349095 | 0.36321745965719776 |  0.00239816283359504  | 0.04897104076487491 | 0.9852190777454486 | 0.5912591313269627 |
|  pi/2  | 2.7519148284313726 | 1.1579503676470588 |  0.544855811925859  |  0.004065450267212431 | 0.06376088351969748 | 0.9972246636710612 | 0.3138279417763978 |
| 3*pi/4 | 16.582529796232222 | 2.7031910803537107 | 0.34767407413079676 | 0.0023848557936416086 |  0.0488349853449513 | 0.9832634126821961 | 0.6314995214214671 |
+--------+--------------------+--------------------+---------------------+-----------------------+---------------------+--------------------+--------------------+

GLCM Matrix for Otsu Thresh Holding Segmentation Image : 
+--------+--------------+-------------------+--------------------+--------------------+--------------------+--------------------+----------------------+
| Angle  |   Contrast   |   Dissimilarity   |    Homogeneity     |        ASM         |       Energy       |    Correlation     |       Entropy        |
+--------+--------------+-------------------+--------------------+--------------------+--------------------+--------------------+----------------------+
|   0    | 1834.8046875 |     7.1953125     | 0.9717835221680559 | 0.7559933557330714 | 0.8694787839464925 | 0.8697195510062574 | 0.001034097351833165 |
|  pi/4  |    1808.0    | 7.090196078431373 | 0.9721957370897796 | 0.7566950033857088 | 0.8698821778756642 | 0.8714373121548846 | 0.001034097351833165 |
|  pi/2  | 775.95703125 |     3.04296875    | 0.9880669727301388 | 0.7714502942218362 | 0.8783224318106855 | 0.9449470772537727 | 0.001034097351833165 |
| 3*pi/4 |    2101.0    | 8.239215686274509 | 0.9676898471380679 | 0.7524715062272356 | 0.8674511549518138 | 0.8505947585437884 | 0.001034097351833165 |
+--------+--------------+-------------------+--------------------+--------------------+--------------------+--------------------+----------------------+

GLCM Matrix for K-Means Clustering Image : 
+--------+---------------------+----------------------+--------------------+---------------------+--------------------+--------------------+-----------------------+
| Angle  |       Contrast      |    Dissimilarity     |    Homogeneity     |         ASM         |       Energy       |    Correlation     |        Entropy        |
+--------+---------------------+----------------------+--------------------+---------------------+--------------------+--------------------+-----------------------+
|   0    | 0.22365196078431374 | 0.11587009803921569  | 0.9528431372549019 |  0.4643897507494113 | 0.6814614814862329 | 0.8636771731902003 | 0.0018020374439914875 |
|  pi/4  |  0.2435678585159554 |  0.1259515570934256  | 0.9487858515955403 | 0.46032846858504284 | 0.6784751053539421 | 0.851485596172084  | 0.0018020374439914875 |
|  pi/2  | 0.11755514705882353 | 0.059436274509803926 |     0.97609375     | 0.48796594240627855 | 0.6985455907857973 | 0.9283821605179876 | 0.0018020374439914875 |
| 3*pi/4 |  0.2614071510957324 |  0.1346559015763168  | 0.9453471741637831 | 0.45671333224245664 | 0.6758056911882709 | 0.8406060345289735 | 0.0018020374439914875 |
+--------+---------------------+----------------------+--------------------+---------------------+--------------------+--------------------+-----------------------+

GLCM Matrix for Common_Rust.JPG

GLCM Matrix for Preprocessed Image : 
+--------+--------------------+--------------------+---------------------+-----------------------+---------------------+--------------------+--------------------+
| Angle  |      Contrast      |   Dissimilarity    |     Homogeneity     |          ASM          |        Energy       |    Correlation     |      Entropy       |
+--------+--------------------+--------------------+---------------------+-----------------------+---------------------+--------------------+--------------------+
|   0    | 16.832766544117646 | 2.7565104166666665 | 0.33976354173812073 | 0.0017431003522157943 | 0.04175045331748859 | 0.9882926403851455 | 0.6765150966891981 |
|  pi/4  | 34.201537870049975 | 3.7213225682429827 |  0.2791632240328607 |  0.001365358634577154 | 0.03695075959404832 | 0.9759781303345028 | 0.8083550704570086 |
|  pi/2  | 14.434941789215687 | 2.186688112745098  | 0.41525020720590916 |  0.002133507235423275 |  0.0461899040421527 | 0.9899056232177595 | 0.6077249461827419 |
| 3*pi/4 | 25.101084198385237 | 3.238815840061515  | 0.30810906866288346 | 0.0015196478567303469 | 0.03898266097549456 | 0.9823668094431979 | 0.7430457578479162 |
+--------+--------------------+--------------------+---------------------+-----------------------+---------------------+--------------------+--------------------+

GLCM Matrix for Otsu Thresh Holding Segmentation Image : 
+--------+--------------+--------------------+--------------------+--------------------+--------------------+--------------------+----------------------+
| Angle  |   Contrast   |   Dissimilarity    |    Homogeneity     |        ASM         |       Energy       |    Correlation     |       Entropy        |
+--------+--------------+--------------------+--------------------+--------------------+--------------------+--------------------+----------------------+
|   0    | 485.09765625 |     1.90234375     | 0.9925399431573525 | 0.9422025261233287 | 0.9706711730155216 | 0.8519600338713433 | 0.001034097351833165 |
|  pi/4  |    619.0     | 2.4274509803921567 | 0.9904807307846092 | 0.9409778840865186 | 0.9700401456055923 | 0.8080504452927942 | 0.001034097351833165 |
|  pi/2  | 489.08203125 |     1.91796875     | 0.9924786695898564 | 0.9425780605857347 | 0.9708645943620225 | 0.8494417955674965 | 0.001034097351833165 |
| 3*pi/4 |    552.0     | 2.164705882352941  | 0.9915110878725433 | 0.9420042978176111 | 0.9705690587575987 | 0.8287764972160546 | 0.001034097351833165 |
+--------+--------------+--------------------+--------------------+--------------------+--------------------+--------------------+----------------------+

GLCM Matrix for K-Means Clustering Image : 
+--------+----------------------+----------------------+--------------------+---------------------+--------------------+--------------------+-----------------------+
| Angle  |       Contrast       |    Dissimilarity     |    Homogeneity     |         ASM         |       Energy       |    Correlation     |        Entropy        |
+--------+----------------------+----------------------+--------------------+---------------------+--------------------+--------------------+-----------------------+
|   0    | 0.059712009803921565 | 0.059712009803921565 | 0.9701439950980393 |  0.4253316590786897 | 0.6521745618150785 | 0.8970934740755782 | 0.0018020374439914875 |
|  pi/4  | 0.08405997693194923  | 0.08405997693194923  | 0.9579700115340253 |  0.4056068868907221 | 0.6368727399494518 | 0.8547765139149943 | 0.0018020374439914875 |
|  pi/2  | 0.05191482843137255  | 0.05191482843137255  | 0.9740425857843138 | 0.43250700308606516 | 0.6576526462244832 | 0.9104000847715279 | 0.0018020374439914875 |
| 3*pi/4 | 0.07020376778162246  | 0.07020376778162246  | 0.9648981161091887 |  0.4169407191892747 | 0.6457094696450368 | 0.8787086044741661 | 0.0018020374439914875 |
+--------+----------------------+----------------------+--------------------+---------------------+--------------------+--------------------+-----------------------+

GLCM Matrix for Cercospora_disease.JPG

GLCM Matrix for Preprocessed Image : 
+--------+--------------------+--------------------+---------------------+-----------------------+---------------------+--------------------+--------------------+
| Angle  |      Contrast      |   Dissimilarity    |     Homogeneity     |          ASM          |        Energy       |    Correlation     |      Entropy       |
+--------+--------------------+--------------------+---------------------+-----------------------+---------------------+--------------------+--------------------+
|   0    | 31.296660539215683 | 3.711182598039216  | 0.31372196189016793 | 0.0010702337479875528 |  0.0327144272147252 | 0.9718351348725657 | 0.7964914501846837 |
|  pi/4  | 41.23577085736256  | 4.304006151480201  | 0.27314471195125894 |  0.000901180851832784 | 0.03001967441250461 | 0.9628906687528724 | 0.8720388379122884 |
|  pi/2  | 8.356295955882358  | 1.7784466911764711 |  0.4882745675810256 | 0.0021301470165846674 | 0.04615351575540771 | 0.9924712875736013 | 0.5659854383844349 |
| 3*pi/4 | 35.96950403690889  | 3.9881737793156473 |  0.2968146287039242 | 0.0009935126539477542 | 0.03152003575422709 | 0.9676301698163754 | 0.8347017491727566 |
+--------+--------------------+--------------------+---------------------+-----------------------+---------------------+--------------------+--------------------+

GLCM Matrix for Otsu Thresh Holding Segmentation Image : 
+--------+---------------+-------------------+--------------------+---------------------+--------------------+--------------------+----------------------+
| Angle  |    Contrast   |   Dissimilarity   |    Homogeneity     |         ASM         |       Energy       |    Correlation     |       Entropy        |
+--------+---------------+-------------------+--------------------+---------------------+--------------------+--------------------+----------------------+
|   0    | 7631.07421875 |    29.92578125    | 0.8826457998531356 |  0.4427636787974802 | 0.6654048983870499 | 0.7413087314670967 | 0.001034097351833165 |
|  pi/4  |     8524.0    | 33.42745098039216 | 0.8689139728723896 |  0.4324509474884781 | 0.6576100269068881 | 0.7110339171660873 | 0.001034097351833165 |
|  pi/2  |  4584.0234375 |     17.9765625    | 0.9295047605957616 | 0.48049011629391336 | 0.6931739437499893 | 0.8447160395514041 | 0.001034097351833165 |
| 3*pi/4 |     8319.0    | 32.62352941176471 | 0.8720665579921878 | 0.43479165772014755 | 0.6593873351226482 | 0.7179805657829333 | 0.001034097351833165 |
+--------+---------------+-------------------+--------------------+---------------------+--------------------+--------------------+----------------------+

GLCM Matrix for K-Means Clustering Image : 
+--------+---------------------+---------------------+--------------------+---------------------+--------------------+--------------------+-----------------------+
| Angle  |       Contrast      |    Dissimilarity    |    Homogeneity     |         ASM         |       Energy       |    Correlation     |        Entropy        |
+--------+---------------------+---------------------+--------------------+---------------------+--------------------+--------------------+-----------------------+
|   0    | 0.26700367647058826 | 0.15364583333333334 | 0.9345128676470589 | 0.31599827843783035 | 0.5621372416392908 | 0.8356504526594405 | 0.0018020374439914875 |
|  pi/4  | 0.31089580930411387 | 0.17931564782775858 | 0.9235001922337563 |  0.305909059967324  | 0.5530904627340124 | 0.8086320390742846 | 0.0023038232996997607 |
|  pi/2  | 0.12872242647058824 | 0.07455575980392157 | 0.9681387867647059 |  0.3492602303228851 | 0.5909824280999267 | 0.9207599802397424 | 0.0018020374439914875 |
| 3*pi/4 | 0.28206074586697427 | 0.16306036139946176 | 0.9303698577470204 | 0.31216111935181234 | 0.5587138080912376 | 0.826382284388029  | 0.0023038232996997607 |
+--------+---------------------+---------------------+--------------------+---------------------+--------------------+--------------------+-----------------------+

GLCM Matrix for Northern_Blight.JPG

GLCM Matrix for Preprocessed Image : 
+--------+--------------------+--------------------+---------------------+-----------------------+---------------------+--------------------+--------------------+
| Angle  |      Contrast      |   Dissimilarity    |     Homogeneity     |          ASM          |        Energy       |    Correlation     |      Entropy       |
+--------+--------------------+--------------------+---------------------+-----------------------+---------------------+--------------------+--------------------+
|   0    | 27.837607230392162 | 3.613893995098039  |  0.2897716593758679 | 0.0010217068095429045 | 0.03196414881618005 | 0.9775007438081286 | 0.8416293675250806 |
|  pi/4  | 41.558400615148024 | 4.408012302960401  | 0.24737721784445862 | 0.0008373203989061081 | 0.02893648905631276 | 0.9664367838629386 | 0.9496666080833613 |
|  pi/2  | 10.878844975490194 | 2.1627604166666665 |  0.4157520470528512 | 0.0015744567659899437 |  0.0396794249705051 | 0.991240967561214  | 0.6523064555680023 |
| 3*pi/4 | 33.16381391772396  | 4.027635524798154  | 0.25806261280536313 | 0.0008796423934780356 | 0.02965876587921412 | 0.9732170998885837 | 0.887606342435279  |
+--------+--------------------+--------------------+---------------------+-----------------------+---------------------+--------------------+--------------------+

GLCM Matrix for Otsu Thresh Holding Segmentation Image : 
+--------+---------------+-------------------+--------------------+---------------------+--------------------+--------------------+----------------------+
| Angle  |    Contrast   |   Dissimilarity   |    Homogeneity     |         ASM         |       Energy       |    Correlation     |       Entropy        |
+--------+---------------+-------------------+--------------------+---------------------+--------------------+--------------------+----------------------+
|   0    | 7850.21484375 |    30.78515625    | 0.8792757536408514 |  0.4697064393192747 | 0.6853513254669277 | 0.7153641189132971 | 0.001034097351833165 |
|  pi/4  |     9332.0    | 36.59607843137255 | 0.8564881739611848 |  0.4527204621414796 | 0.6728450506182531 | 0.6618120693497094 | 0.001034097351833165 |
|  pi/2  |  5653.828125  |     22.171875     | 0.9130528077230646 | 0.49583217317257794 | 0.7041535153448983 | 0.7953089513354413 | 0.001034097351833165 |
| 3*pi/4 |     8993.0    | 35.26666666666667 | 0.8617014732568511 | 0.45647061626106894 | 0.6756260920517124 | 0.674092699352676  | 0.001034097351833165 |
+--------+---------------+-------------------+--------------------+---------------------+--------------------+--------------------+----------------------+

GLCM Matrix for K-Means Clustering Image : 
+--------+---------------------+---------------------+--------------------+---------------------+--------------------+--------------------+-----------------------+
| Angle  |       Contrast      |    Dissimilarity    |    Homogeneity     |         ASM         |       Energy       |    Correlation     |        Entropy        |
+--------+---------------------+---------------------+--------------------+---------------------+--------------------+--------------------+-----------------------+
|   0    | 0.16842830882352944 | 0.10672487745098042 | 0.9528079044117648 | 0.34231419394264684 | 0.5850762291724445 | 0.8386394695238478 | 0.0018020374439914875 |
|  pi/4  | 0.20390618992695117 | 0.13064206074586698 | 0.942005382545175  | 0.33012147251796364 | 0.5745619831819397 | 0.8047205023719058 | 0.0023038232996997607 |
|  pi/2  | 0.09603247549019608 | 0.06521139705882353 | 0.9704764093137255 |  0.3592102683190885 | 0.5993415289457994 | 0.908199529336569  | 0.0018020374439914875 |
| 3*pi/4 |  0.1830065359477124 | 0.11893886966551326 | 0.9469373317954632 |  0.3344784495833901 | 0.5783411187036507 | 0.8247315320078645 | 0.0023038232996997607 |
+--------+---------------------+---------------------+--------------------+---------------------+--------------------+--------------------+-----------------------+

Applying Feature Selection using RandomForest¶


In [11]:
from sklearn.ensemble import RandomForestClassifier

def feature_extraction(image):
    # Calculate GLCM for all angles
    glcms = []
    Theta = ["0", "pi/4", "pi/2", "3pi/4"]
    theta = [0, np.pi/4, np.pi/2, 3*np.pi/4]  # angles for GLCM
    d = 1
    for angle in theta:
        glcm = graycomatrix(image, distances=[d], angles=[angle], levels=256, symmetric=True, normed=True)
        glcms.append(glcm)

    # Extract GLCM features
    features = []
    for glcm in glcms:
        contrast = graycoprops(glcm, 'contrast')
        dissimilarity = graycoprops(glcm, 'dissimilarity')
        homogeneity = graycoprops(glcm, 'homogeneity')
        energy = graycoprops(glcm, 'energy')
        correlation = graycoprops(glcm, 'correlation')
        ASM = graycoprops(glcm, 'ASM')
        entropy = shannon_entropy(glcm)

        row = [contrast[0][0], dissimilarity[0][0], homogeneity[0][0], ASM[0][0], energy[0][0], correlation[0][0], entropy]
        features.append(row)

    # Fit Random Forest Classifier and extract feature importances
    X = np.array(features)
    y = np.array([0, 1, 2, 3])  # labels for each angle
    clf = RandomForestClassifier(n_estimators=100, random_state=42)
    clf.fit(X, y)
    feature_importances = clf.feature_importances_

    # Print extracted features
    print("Extracted Features:")
    headers = ["Angle", "Contrast", "Dissimilarity", "Homogeneity", "ASM", "Energy", "Correlation", "Entropy"]
    table = PrettyTable(headers)
    i = 0
    for glcm in glcms:
        row = [Theta[i], features[i][0], features[i][1], features[i][2], features[i][3], features[i][4], features[i][5], features[i][6]]
        table.add_row(row)
        i += 1
    print(table)

    # Print selected features
    print("\nSelected Features:")
    headers = ["Feature", "Importance"]
    table = PrettyTable(headers)
    feature_names = ["Contrast", "Dissimilarity", "Homogeneity", "ASM", "Energy", "Correlation", "Entropy"]
    for i in range(len(feature_names)):
        row = [feature_names[i], feature_importances[i]]
        table.add_row(row)
    print(table)
    
    # Return selected features
    selected_features = X[:, feature_importances.argsort()[::-1][:3]]  # Select top 3 features

Printing Selected Features for all Classes¶


In [12]:
import warnings
warnings.filterwarnings('ignore')

# Define the dimensions of the resized images
image_size = (256, 256)

# Loop over each image file in the dataset folder
for filename in os.listdir(dataset_path):
    print()
    print("Feature Selection for " + '{}'.format(os.path.basename(filename)))    
    print()
    # Load the image
    image = cv2.imread(os.path.join(dataset_path, filename))

    # Resize the image
    image = cv2.resize(image, image_size)

    # Convert the image to grayscale
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # Apply Gaussian blur to reduce noise
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)

    # Apply Otsu Thresh holding to the preprocessed image
    otsu_img, thresh = apply_otsu(blurred)

    print(feature_extraction(otsu_img))
Feature Selection for Healthy.jpg

Extracted Features:
+-------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+----------------------+
| Angle |      Contrast      |   Dissimilarity    |    Homogeneity     |        ASM         |       Energy       |    Correlation     |       Entropy        |
+-------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+----------------------+
|   0   |   1024.98046875    |     4.01953125     | 0.9842373747616339 | 0.7847624855965479 | 0.8858682100609254 | 0.9210763978592833 | 0.001034097351833165 |
|  pi/4 | 1021.9999999999999 | 4.007843137254902  | 0.9842832097930059 | 0.7850406708093374 | 0.8860252089017204 | 0.9212136683611595 | 0.001034097351833165 |
|  pi/2 |    360.5859375     |     1.4140625      | 0.9944547421416049 |  0.79458425085529  | 0.8913945539744396 | 0.9722595745568905 | 0.001034097351833165 |
| 3pi/4 |       1173.0       | 4.6000000000000005 | 0.9819610617291545 | 0.7828087977873828 | 0.8847648262602796 | 0.9095676216867384 | 0.001034097351833165 |
+-------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+----------------------+

Selected Features:
+---------------+---------------------+
|    Feature    |      Importance     |
+---------------+---------------------+
|    Contrast   | 0.18503401360544217 |
| Dissimilarity | 0.22040816326530618 |
|  Homogeneity  | 0.16394557823129252 |
|      ASM      | 0.11904761904761905 |
|     Energy    | 0.12585034013605445 |
|  Correlation  | 0.18571428571428572 |
|    Entropy    |         0.0         |
+---------------+---------------------+
None

Feature Selection for Common_Rust.JPG

Extracted Features:
+-------+-------------------+---------------------+--------------------+--------------------+--------------------+--------------------+----------------------+
| Angle |      Contrast     |    Dissimilarity    |    Homogeneity     |        ASM         |       Energy       |    Correlation     |       Entropy        |
+-------+-------------------+---------------------+--------------------+--------------------+--------------------+--------------------+----------------------+
|   0   |      39.84375     |       0.15625       | 0.9993872643250392 | 0.9575619695737516 | 0.9785509539997146 | 0.9853500199030347 | 0.001034097351833165 |
|  pi/4 |       100.0       | 0.39215686274509803 | 0.9984621536000985 | 0.9573914311193416 | 0.9784638118598672 | 0.962557698284641  | 0.001034097351833165 |
|  pi/2 |    74.70703125    |      0.29296875     | 0.9988511206094485 | 0.957393433579295  | 0.9784648351265849 | 0.9722883486189138 | 0.001034097351833165 |
| 3pi/4 | 75.00000000000001 |  0.2941176470588236 | 0.9988466152000739 | 0.9577895975596291 | 0.9786672557920946 | 0.9719081966866367 | 0.001034097351833165 |
+-------+-------------------+---------------------+--------------------+--------------------+--------------------+--------------------+----------------------+

Selected Features:
+---------------+---------------------+
|    Feature    |      Importance     |
+---------------+---------------------+
|    Contrast   | 0.19115646258503396 |
| Dissimilarity |  0.2176870748299319 |
|  Homogeneity  | 0.15918367346938778 |
|      ASM      | 0.11428571428571431 |
|     Energy    | 0.12925170068027214 |
|  Correlation  | 0.18843537414965983 |
|    Entropy    |         0.0         |
+---------------+---------------------+
None

Feature Selection for Cercospora_disease.JPG

Extracted Features:
+-------+---------------+--------------------+--------------------+---------------------+--------------------+--------------------+----------------------+
| Angle |    Contrast   |   Dissimilarity    |    Homogeneity     |         ASM         |       Energy       |    Correlation     |       Entropy        |
+-------+---------------+--------------------+--------------------+---------------------+--------------------+--------------------+----------------------+
|   0   |  3719.4140625 |     14.5859375     | 0.9428011247424107 | 0.48733854758010736 | 0.6980963741347661 | 0.8753094035642773 | 0.001034097351833165 |
|  pi/4 |     4400.0    | 17.254901960784313 | 0.9323347584043304 |  0.4782065862049036 | 0.6915248268897535 | 0.8524843729025774 | 0.001034097351833165 |
|  pi/2 | 1959.31640625 |     7.68359375     | 0.9698687231838033 |  0.5118097582050398 | 0.7154088049535313 | 0.934348704693716  | 0.001034097351833165 |
| 3pi/4 |     4085.0    | 16.019607843137255 | 0.9371789745640204 | 0.48242317341347285 | 0.6945668962839165 | 0.8630438311653013 | 0.001034097351833165 |
+-------+---------------+--------------------+--------------------+---------------------+--------------------+--------------------+----------------------+

Selected Features:
+---------------+---------------------+
|    Feature    |      Importance     |
+---------------+---------------------+
|    Contrast   |  0.182312925170068  |
| Dissimilarity | 0.22040816326530613 |
|  Homogeneity  | 0.16122448979591839 |
|      ASM      | 0.12312925170068029 |
|     Energy    | 0.12585034013605445 |
|  Correlation  | 0.18707482993197277 |
|    Entropy    |         0.0         |
+---------------+---------------------+
None

Feature Selection for Northern_Blight.JPG

Extracted Features:
+-------+---------------+--------------------+--------------------+--------------------+--------------------+--------------------+----------------------+
| Angle |    Contrast   |   Dissimilarity    |    Homogeneity     |        ASM         |       Energy       |    Correlation     |       Entropy        |
+-------+---------------+--------------------+--------------------+--------------------+--------------------+--------------------+----------------------+
|   0   |  3647.6953125 |     14.3046875     | 0.9439040489573401 | 0.5318125104189194 | 0.729254763727272  | 0.8649042779291376 | 0.001034097351833165 |
|  pi/4 |     4368.0    | 17.129411764705882 | 0.9328268692522991 | 0.5219107750974435 | 0.7224339243816306 | 0.8383010869545068 | 0.001034097351833165 |
|  pi/2 | 2092.79296875 |     8.20703125     | 0.9678160586726847 | 0.5530408896358597 | 0.7436671901031131 | 0.9225983101832996 | 0.001034097351833165 |
| 3pi/4 |     3989.0    | 15.64313725490196  | 0.938655307107926  | 0.5269965463553854 | 0.7259452777967396 | 0.8523290327871963 | 0.001034097351833165 |
+-------+---------------+--------------------+--------------------+--------------------+--------------------+--------------------+----------------------+

Selected Features:
+---------------+---------------------+
|    Feature    |      Importance     |
+---------------+---------------------+
|    Contrast   |  0.182312925170068  |
| Dissimilarity | 0.22040816326530613 |
|  Homogeneity  | 0.16122448979591839 |
|      ASM      | 0.12312925170068029 |
|     Energy    | 0.12585034013605445 |
|  Correlation  | 0.18707482993197277 |
|    Entropy    |         0.0         |
+---------------+---------------------+
None

Feature Selection using Hill Climbing¶


In [13]:
# Define the properties to be extracted from GLCM
props = ['contrast', 'dissimilarity', 'homogeneity', 'energy', 'correlation', 'ASM', 'entropy']

# Define the distance and angle offsets for GLCM
distances = [1]
angles = [0, np.pi/4, np.pi/2, 3*np.pi/4]

# Define the path to the dataset
data_path = '/content/drive/MyDrive/plant_data/Preprocessed_otsu_dataset'

# Define the output file path
output_file = '/content/drive/MyDrive/plant_data/plant_features.csv'

# Initialize an empty list to store the feature vectors
feature_vectors = []

# Loop over the classes
for class_name in os.listdir(data_path):
    class_path = os.path.join(data_path, class_name)
    
    # Loop over the images in the class
    for file_name in os.listdir(class_path):
        file_path = os.path.join(class_path, file_name)
    
        # Load the image and convert it to grayscale
        img = cv2.imread(file_path)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
        # Compute the GLCM for each distance and angle offset
        glcm = graycomatrix(gray, distances=distances, angles=angles, symmetric=True, normed=True)
    
        # Calculate the required texture features from the GLCM
        feature_vector = []
        for i, prop in enumerate(props[:-1]):
            # Add the feature column with the respective angle
            for j, angle in enumerate(angles):
                feature_name = f"{prop}_angle_{j}"
                feature_vector.append(graycoprops(glcm, prop)[0, j])
    
        # Calculate the entropy of the GLCM
        entropy = shannon_entropy(glcm)
        feature_vector.append(entropy)
    
        # Add the class label to the feature vector
        feature_vector.append(class_name)
    
        # Add the feature vector to the list
        feature_vectors.append(feature_vector)

# Convert the list of feature vectors to a pandas DataFrame
feature_df = pd.DataFrame(feature_vectors, columns=[f"{props[i]}_angle_{j}" for i in range(len(props)-1) for j in range(len(angles))] + ['entropy', 'class'])

# Save the feature DataFrame to a CSV file
feature_df.to_csv(output_file, index=False)
In [14]:
featuress = pd.read_csv('/content/drive/MyDrive/plant_data/plant_features.csv')
In [15]:
featuress
Out[15]:
contrast_angle_0 contrast_angle_1 contrast_angle_2 contrast_angle_3 dissimilarity_angle_0 dissimilarity_angle_1 dissimilarity_angle_2 dissimilarity_angle_3 homogeneity_angle_0 homogeneity_angle_1 ... correlation_angle_0 correlation_angle_1 correlation_angle_2 correlation_angle_3 ASM_angle_0 ASM_angle_1 ASM_angle_2 ASM_angle_3 entropy class
0 5050.189706 6313.012042 4942.125996 5124.622422 20.395343 25.291596 19.984972 20.623037 0.747732 0.753703 ... 0.817412 0.771643 0.821160 0.814627 0.261027 0.269387 0.258522 0.274999 0.048530 Cercospora_disease_otsu
1 7552.057384 8573.409104 6943.024464 7357.023360 30.211091 34.158877 27.833410 29.382576 0.724608 0.735324 ... 0.697362 0.656047 0.720879 0.704852 0.331859 0.340208 0.332695 0.344119 0.048867 Cercospora_disease_otsu
2 9076.268352 9915.324983 6049.273529 9587.251888 36.475429 39.672695 24.614032 38.387051 0.607150 0.629335 ... 0.661731 0.630395 0.775161 0.642619 0.140020 0.152364 0.144698 0.153413 0.050547 Cercospora_disease_otsu
3 6079.382154 7155.495794 6413.314216 5471.549896 24.465977 28.624898 25.790809 22.007013 0.727090 0.737549 ... 0.806741 0.772509 0.796095 0.826045 0.208055 0.216313 0.203393 0.223235 0.048798 Cercospora_disease_otsu
4 12145.338649 12631.411626 5498.596247 12653.951542 48.545144 50.362676 22.479917 50.454425 0.570600 0.594454 ... 0.602231 0.586187 0.819779 0.585448 0.121104 0.130801 0.135078 0.130271 0.051877 Cercospora_disease_otsu
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
3860 8563.115165 7507.642199 6656.587531 11838.204060 34.460600 30.215087 26.998070 47.225790 0.613614 0.653600 ... 0.716037 0.751159 0.779462 0.607629 0.147091 0.163363 0.148146 0.150750 0.052270 Healthy_leaves_otsu
3861 7732.141376 8091.892072 4172.288082 8046.484998 30.972963 32.319016 17.013971 32.138793 0.706005 0.723053 ... 0.684419 0.669818 0.829936 0.671664 0.279677 0.291712 0.287520 0.292893 0.050353 Healthy_leaves_otsu
3862 1852.681112 2108.920200 1001.571768 2154.985975 7.522258 8.497224 4.184329 8.678585 0.889590 0.896261 ... 0.942874 0.934969 0.969117 0.933548 0.357698 0.364092 0.361839 0.363940 0.039973 Healthy_leaves_otsu
3863 2111.761029 2346.671111 810.900965 2160.700331 8.518964 9.413995 3.409911 8.683599 0.891495 0.897387 ... 0.902946 0.892114 0.962638 0.900664 0.513848 0.520118 0.525106 0.521477 0.039354 Healthy_leaves_otsu
3864 6029.826976 7522.938900 6820.319868 6837.076417 24.392080 30.173041 27.514997 27.477309 0.685062 0.695848 ... 0.810406 0.763610 0.785627 0.785162 0.182450 0.189073 0.176293 0.191325 0.050282 Healthy_leaves_otsu

3865 rows × 26 columns

Apply Hill-Climbing to all 4-Classes for feature selection¶


In [16]:
import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from itertools import combinations

def calculate_cfs_score(data, features, target):
    k = len(features)

    # Compute the average correlation between features and target
    rzc = np.mean(data[features + [target]].corr().iloc[:-1, -1].values)

    # Compute the average inter-correlation between features
    rij = np.mean(data[features].corr().values)

    # Calculate the CFS score
    cfs_score = k * rzc / (np.sqrt(k + k * (k - 1) * rij))

    return cfs_score

def hill_climbing(data, target, max_iterations):
    best_features = []
    best_score = 0
    all_features = list(data.columns[:-1])
    current_features = list(np.random.choice(all_features, size=5, replace=False))

    for i in range(max_iterations):
        neighbors = []
        for feature in all_features:
            if feature not in current_features:
                neighbors.append(current_features + [feature])

        neighbor_scores = []
        for features in neighbors:
            X = data[features]
            y = data[target]
            model = LogisticRegression()
            model.fit(X, y)
            y_pred = model.predict(X)
            score = accuracy_score(y, y_pred)
            neighbor_scores.append(score)

        # Compute the CFS scores for the neighbor solutions
        cfs_scores = [calculate_cfs_score(data, features, target) for features in neighbors]

        # Find the index of the neighbor with the highest CFS score
        best_neighbor_idx = np.argmax(cfs_scores)
        best_neighbor_score = neighbor_scores[best_neighbor_idx]

        # Update the current features with the best neighbor if its score is higher than the current score
        if best_neighbor_score > best_score:
            best_score = best_neighbor_score
            best_features = neighbors[best_neighbor_idx]
            current_features = best_features

    print("Selected features:", best_features)
    print("Accuracy:", best_score)

    selected_df = data[best_features + [target]]

    return best_features, selected_df
In [17]:
import warnings
warnings.filterwarnings("ignore")

# Load the original feature DataFrame
feature_df = pd.read_csv('/content/drive/MyDrive/plant_data/plant_features.csv')

# feature_df = pd.DataFrame(feature_df)

# Apply feature selection using hill climbing
selected_features, selected_df = hill_climbing(feature_df, "class", 100)

# Save the selected feature DataFrame to a CSV file
output_file = '/content/drive/MyDrive/plant_data/selected_plant_features.csv'
selected_df.to_csv(output_file, index=False)
Selected features: ['dissimilarity_angle_3', 'energy_angle_3', 'contrast_angle_1', 'dissimilarity_angle_2', 'homogeneity_angle_3', 'contrast_angle_2']
Accuracy: 0.5948253557567917

Visualisation of the Selected features on our Preprocessed Dataset¶


1. Bar Chart: Class Distribution¶


This will display a bar chart showing the count of samples for each class.

In [18]:
import pandas as pd
import matplotlib.pyplot as plt

# Load the dataset
data = pd.read_csv('/content/drive/MyDrive/plant_data/selected_plant_features.csv')

class_counts = data['class'].value_counts()

plt.figure(figsize=(8, 6))
plt.bar(class_counts.index, class_counts.values)
plt.xlabel('Class')
plt.ylabel('Count')
plt.title('Class Distribution')
plt.xticks(rotation=90)  # Rotates the x-axis labels by 90 degrees
plt.tight_layout()  # Adjusts the spacing to prevent overlapping
plt.show()

2. Box Plot: Feature Comparison¶


This will show a box plot for each feature, grouped by class, allowing us to compare the distributions and identify any potential differences.

In [19]:
plt.figure(figsize=(10, 6))
boxplot = data.drop('class', axis=1).boxplot()
plt.title('Feature Comparison')
plt.xlabel('Features')
plt.ylabel('Value')
plt.xticks(rotation=90)  # Rotates the x-axis labels by 90 degrees
plt.tight_layout()  # Adjusts the spacing to prevent overlapping
plt.show()

3. Pairwise Scatter Plot: Feature Relationships¶


This will generate a scatter plot matrix where each point represents the relationship between two features, with different colors indicating different classes.

In [20]:
import seaborn as sns
import matplotlib.pyplot as plt

# Generate the pair plot
sns.pairplot(data, hue='class')

# Set the title
plt.suptitle('Pairwise Scatter Plot', fontweight='bold')

# Display the plot
plt.show()

4. Histogram: Distribution of a Single Feature¶


This will display a histogram showing the distribution of the 'contrast' feature.

In [35]:
# Load the dataset
data = pd.read_csv('/content/drive/MyDrive/plant_data/selected_plant_features.csv')

plt.figure(figsize=(8, 6))
plt.hist(data['contrast_angle_1'], bins=20)
plt.xlabel('Contrast at pi/4')
plt.ylabel('Frequency')
plt.title('Distribution of contrast at GLCM angle pi/4')
plt.show()

5. Heatmap: Correlation Matrix¶


This will generate a heatmap where each cell represents the correlation between two features. Higher values indicate stronger positive correlation, while lower values indicate negative correlation.

In [21]:
plt.figure(figsize=(10, 8))
corr_matrix = data.drop('class', axis=1).corr()
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm')
plt.title('Correlation Matrix')
plt.show()
In [22]:
# Load the dataset
data = pd.read_csv('/content/drive/MyDrive/plant_data/selected_plant_features.csv')
In [37]:
from sklearn.cluster import KMeans
import numpy as np

# Select the numerical features for clustering
features = ['dissimilarity_angle_3', 'energy_angle_3', 'contrast_angle_1', 'dissimilarity_angle_2', 'homogeneity_angle_3', 'contrast_angle_2']

# Extract the feature values
X = data[features].values

# Define the number of clusters
n_clusters = 4

# Perform K-means clustering
kmeans = KMeans(n_clusters=n_clusters, random_state=42)
kmeans.fit(X)

# Get the cluster labels
labels = kmeans.labels_

# Add the cluster labels to the dataset
data['cluster'] = labels

# Visualize the clusters
plt.figure(figsize=(10, 6))
colors = ['red', 'green', 'blue', 'orange']

for cluster_id, color in zip(range(n_clusters), colors):
    cluster_data = data[data['cluster'] == cluster_id]
    plt.scatter(cluster_data['contrast_angle_2'], cluster_data['contrast_angle_1'], c=color, label=f'Cluster {cluster_id}')

plt.xlabel('contrast_angle_2')
plt.ylabel('Contrast at 0 degree')
plt.title('K-means Clustering')
plt.legend()
plt.show()

MACHINE LEARNING¶


Model 1: CNN¶


In [ ]:
# pip install tensorflow keras
In [39]:
import os
import cv2
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
from tensorflow.keras.utils import to_categorical
In [40]:
# Define the path to the dataset
data_path = '/content/drive/MyDrive/DATA_SET'
In [41]:
# Define the class names
class_names = os.listdir(data_path)

# Initialize empty lists for images and labels
images = []
labels = []

# Loop over the classes
for i, class_name in enumerate(class_names):
    class_path = os.path.join(data_path, class_name)
    
    # Loop over the images in the class
    for file_name in os.listdir(class_path):
        file_path = os.path.join(class_path, file_name)
    
        # Load the image and resize it to 128x128 pixels
        img = cv2.imread(file_path)
        img = cv2.resize(img, (128, 128))
    
        # Add the image and label to the lists
        images.append(img)
        labels.append(i)

# Convert the image and label lists to numpy arrays
images = np.array(images)
labels = np.array(labels)
In [42]:
# Split the data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(images, labels, test_size=0.2, random_state=42,shuffle="True")

# Convert the labels to one-hot encoding
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
In [43]:
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.preprocessing.image import ImageDataGenerator

CNN_model = Sequential([
    Conv2D(64, (3, 3), activation='relu', input_shape=(128, 128, 3)),
    BatchNormalization(),
    MaxPooling2D((2, 2)),
    Conv2D(128, (3, 3), activation='relu'),
    BatchNormalization(),
    MaxPooling2D((2, 2)),
    Conv2D(256, (3, 3), activation='relu'),
    BatchNormalization(),
    MaxPooling2D((2, 2)),
    Flatten(),
    Dense(512, activation='relu'),
    Dropout(0.5),
    Dense(256, activation='relu'),
    Dropout(0.5),
    Dense(len(class_names), activation='softmax')
])

CNN_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# Train the model with data augmentation
datagen = ImageDataGenerator(
    rotation_range=20,
    width_shift_range=0.1,
    height_shift_range=0.1,
    horizontal_flip=True,
    vertical_flip=True
)

datagen.fit(X_train)

CNN_model.fit(datagen.flow(X_train, y_train, batch_size=32), validation_data=(X_test, y_test), epochs=20)
Epoch 1/20
97/97 [==============================] - 484s 5s/step - loss: 2.7307 - accuracy: 0.8069 - val_loss: 46.1722 - val_accuracy: 0.5940
Epoch 2/20
97/97 [==============================] - 475s 5s/step - loss: 0.9869 - accuracy: 0.8523 - val_loss: 8.8509 - val_accuracy: 0.7095
Epoch 3/20
97/97 [==============================] - 460s 5s/step - loss: 0.7741 - accuracy: 0.8484 - val_loss: 10.3123 - val_accuracy: 0.6783
Epoch 4/20
97/97 [==============================] - 457s 5s/step - loss: 0.7175 - accuracy: 0.8767 - val_loss: 0.9377 - val_accuracy: 0.8405
Epoch 5/20
97/97 [==============================] - 456s 5s/step - loss: 0.4320 - accuracy: 0.8926 - val_loss: 0.6035 - val_accuracy: 0.8846
Epoch 6/20
97/97 [==============================] - 472s 5s/step - loss: 0.4219 - accuracy: 0.8922 - val_loss: 0.4086 - val_accuracy: 0.8911
Epoch 7/20
97/97 [==============================] - 467s 5s/step - loss: 0.9288 - accuracy: 0.8987 - val_loss: 0.9206 - val_accuracy: 0.8768
Epoch 8/20
97/97 [==============================] - 487s 5s/step - loss: 0.6662 - accuracy: 0.8965 - val_loss: 0.9148 - val_accuracy: 0.8534
Epoch 9/20
97/97 [==============================] - 466s 5s/step - loss: 0.3795 - accuracy: 0.8981 - val_loss: 0.4253 - val_accuracy: 0.8314
Epoch 10/20
97/97 [==============================] - 470s 5s/step - loss: 0.3408 - accuracy: 0.9010 - val_loss: 5.9163 - val_accuracy: 0.8612
Epoch 11/20
97/97 [==============================] - 456s 5s/step - loss: 0.8466 - accuracy: 0.8909 - val_loss: 2.3378 - val_accuracy: 0.7056
Epoch 12/20
97/97 [==============================] - 477s 5s/step - loss: 0.3460 - accuracy: 0.8909 - val_loss: 0.8246 - val_accuracy: 0.8353
Epoch 13/20
97/97 [==============================] - 469s 5s/step - loss: 0.4706 - accuracy: 0.8929 - val_loss: 0.3819 - val_accuracy: 0.9105
Epoch 14/20
97/97 [==============================] - 546s 6s/step - loss: 0.4297 - accuracy: 0.8961 - val_loss: 4.6754 - val_accuracy: 0.5875
Epoch 15/20
97/97 [==============================] - 579s 6s/step - loss: 0.3958 - accuracy: 0.9049 - val_loss: 0.7367 - val_accuracy: 0.9274
Epoch 16/20
97/97 [==============================] - 581s 6s/step - loss: 0.5175 - accuracy: 0.9205 - val_loss: 0.5941 - val_accuracy: 0.7393
Epoch 17/20
97/97 [==============================] - 549s 6s/step - loss: 0.7345 - accuracy: 0.9283 - val_loss: 1.1091 - val_accuracy: 0.9313
Epoch 18/20
97/97 [==============================] - 498s 5s/step - loss: 0.9140 - accuracy: 0.8896 - val_loss: 2.6170 - val_accuracy: 0.4669
Epoch 19/20
97/97 [==============================] - 475s 5s/step - loss: 0.4281 - accuracy: 0.8770 - val_loss: 0.5049 - val_accuracy: 0.7471
Epoch 20/20
97/97 [==============================] - 482s 5s/step - loss: 0.2973 - accuracy: 0.9104 - val_loss: 1.0613 - val_accuracy: 0.7224
Out[43]:
<keras.callbacks.History at 0x7fb6e8d2e5c0>
In [44]:
# Save the model
CNN_model.save('/content/drive/MyDrive/plant_data/plant_model.h5')
In [45]:
from sklearn.metrics import accuracy_score, confusion_matrix

# Convert the one-hot encoded y_test to the original format
y_test_orig = np.argmax(y_test, axis=1)

y_pred = CNN_model.predict(X_test)
y_pred = np.argmax(y_pred, axis=1)


# Calculate the accuracy score
accuracy = accuracy_score(y_test_orig, y_pred)
print("Accuracy:", accuracy)
25/25 [==============================] - 34s 1s/step
Accuracy: 0.7224383916990921
In [46]:
# Calculate the confusion matrix
cm = confusion_matrix(y_test_orig, y_pred)

print(classification_report(y_test_orig, y_pred))
              precision    recall  f1-score   support

           0       0.37      1.00      0.54       125
           1       1.00      1.00      1.00       233
           2       0.00      0.00      0.00       185
           3       1.00      0.87      0.93       228

    accuracy                           0.72       771
   macro avg       0.59      0.72      0.62       771
weighted avg       0.66      0.72      0.67       771

In [47]:
import seaborn as sns

# Visualize the confusion matrix
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, cmap='Blues', fmt='g')
plt.xlabel('Predicted')
plt.ylabel('True')
plt.show()

Model 2: ANN¶


In [23]:
import pandas as pd

# Read the CSV file into a dataframe
df = pd.read_csv('/content/drive/MyDrive/plant_data/selected_plant_features.csv')

# Shuffle the rows of the dataframe
shuffled_df = df.sample(frac=1)

# Write the shuffled dataframe back to a CSV file
shuffled_df.to_csv('shuffled_filename.csv', index=False)
In [38]:
# shuffled_df
Out[38]:
dissimilarity_angle_3 energy_angle_3 contrast_angle_1 dissimilarity_angle_2 homogeneity_angle_3 contrast_angle_2 class
2881 27.255855 0.444165 8986.417670 27.417785 0.696977 6793.814599 Healthy_leaves_otsu
3807 35.402261 0.448380 7949.364475 22.964154 0.675654 5656.887806 Healthy_leaves_otsu
2285 48.659577 0.342853 12989.970288 41.243566 0.586385 10267.570037 Northern_Blight_disease_otsu
1035 5.835509 0.592812 1368.636309 4.482629 0.886576 1063.596844 Common_rust_otsu
2536 32.601538 0.407936 8161.424068 22.678079 0.673891 5579.457736 Northern_Blight_disease_otsu
... ... ... ... ... ... ... ...
1087 5.771811 0.610732 1498.943206 4.657108 0.903361 1121.015196 Common_rust_otsu
2251 62.126151 0.272311 15393.137762 44.316621 0.500470 11007.293888 Northern_Blight_disease_otsu
1341 7.231111 0.608193 2094.976794 6.532858 0.887465 1587.514231 Common_rust_otsu
1548 2.202122 0.702886 434.618839 1.092816 0.962246 253.192019 Common_rust_otsu
272 20.286736 0.523268 5120.751511 10.272794 0.798534 2494.623866 Cercospora_disease_otsu

3865 rows × 7 columns

In [24]:
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import to_categorical
import seaborn as sns
from sklearn.metrics import accuracy_score, confusion_matrix

# Load the feature data
feature_df = pd.read_csv('shuffled_filename.csv')
# feature_df = pd.read_csv('/content/drive/MyDrive/plant_data/selected_plant_features.csv')

# Convert the class labels to one-hot encoded vectors
y = to_categorical(feature_df['class'].astype('category').cat.codes)

# Split the data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(feature_df.drop('class', axis=1), y, test_size=0.2, random_state=42,shuffle="True")

# Define the model architecture
ANN_model = Sequential()
ANN_model.add(Dense(128, input_dim=X_train.shape[1], activation='relu'))
ANN_model.add(Dense(64, activation='relu'))
ANN_model.add(Dense(32, activation='relu'))
ANN_model.add(Dense(y.shape[1], activation='softmax'))

# Compile the model
ANN_model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

# Train the model
history = ANN_model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=100, batch_size=32)

# Evaluate the model on the test data
loss, accuracy = ANN_model.evaluate(X_test, y_test)
print('Test Loss:', loss)
print('Test Accuracy:', accuracy)
Epoch 1/100
97/97 [==============================] - 2s 5ms/step - loss: 34.9938 - accuracy: 0.2972 - val_loss: 20.4185 - val_accuracy: 0.4179
Epoch 2/100
97/97 [==============================] - 0s 3ms/step - loss: 11.8532 - accuracy: 0.3228 - val_loss: 14.2569 - val_accuracy: 0.1876
Epoch 3/100
97/97 [==============================] - 0s 3ms/step - loss: 9.3213 - accuracy: 0.3231 - val_loss: 11.8784 - val_accuracy: 0.4476
Epoch 4/100
97/97 [==============================] - 0s 3ms/step - loss: 7.2681 - accuracy: 0.3858 - val_loss: 8.5258 - val_accuracy: 0.2924
Epoch 5/100
97/97 [==============================] - 0s 3ms/step - loss: 9.5231 - accuracy: 0.3752 - val_loss: 14.0318 - val_accuracy: 0.3182
Epoch 6/100
97/97 [==============================] - 0s 3ms/step - loss: 9.1552 - accuracy: 0.4030 - val_loss: 10.5751 - val_accuracy: 0.2122
Epoch 7/100
97/97 [==============================] - 0s 3ms/step - loss: 8.2749 - accuracy: 0.4023 - val_loss: 7.3547 - val_accuracy: 0.3247
Epoch 8/100
97/97 [==============================] - 0s 3ms/step - loss: 6.4797 - accuracy: 0.4162 - val_loss: 14.8129 - val_accuracy: 0.2962
Epoch 9/100
97/97 [==============================] - 0s 2ms/step - loss: 8.8659 - accuracy: 0.4162 - val_loss: 10.4672 - val_accuracy: 0.3648
Epoch 10/100
97/97 [==============================] - 0s 3ms/step - loss: 7.0250 - accuracy: 0.4434 - val_loss: 5.2180 - val_accuracy: 0.3907
Epoch 11/100
97/97 [==============================] - 0s 2ms/step - loss: 3.9332 - accuracy: 0.5116 - val_loss: 2.8331 - val_accuracy: 0.5705
Epoch 12/100
97/97 [==============================] - 0s 3ms/step - loss: 4.4047 - accuracy: 0.4589 - val_loss: 5.6657 - val_accuracy: 0.5265
Epoch 13/100
97/97 [==============================] - 0s 2ms/step - loss: 4.7613 - accuracy: 0.4512 - val_loss: 6.9704 - val_accuracy: 0.3118
Epoch 14/100
97/97 [==============================] - 0s 3ms/step - loss: 3.6283 - accuracy: 0.5097 - val_loss: 2.9468 - val_accuracy: 0.5485
Epoch 15/100
97/97 [==============================] - 0s 3ms/step - loss: 5.1570 - accuracy: 0.4774 - val_loss: 4.9314 - val_accuracy: 0.5201
Epoch 16/100
97/97 [==============================] - 0s 3ms/step - loss: 4.2838 - accuracy: 0.5201 - val_loss: 5.3273 - val_accuracy: 0.5821
Epoch 17/100
97/97 [==============================] - 0s 3ms/step - loss: 4.1469 - accuracy: 0.4735 - val_loss: 3.9953 - val_accuracy: 0.5640
Epoch 18/100
97/97 [==============================] - 0s 2ms/step - loss: 3.6844 - accuracy: 0.5301 - val_loss: 4.6758 - val_accuracy: 0.5433
Epoch 19/100
97/97 [==============================] - 0s 3ms/step - loss: 2.8360 - accuracy: 0.5408 - val_loss: 2.7865 - val_accuracy: 0.6352
Epoch 20/100
97/97 [==============================] - 0s 2ms/step - loss: 2.8810 - accuracy: 0.5223 - val_loss: 3.3421 - val_accuracy: 0.5563
Epoch 21/100
97/97 [==============================] - 0s 3ms/step - loss: 3.5800 - accuracy: 0.4981 - val_loss: 2.0187 - val_accuracy: 0.5433
Epoch 22/100
97/97 [==============================] - 0s 3ms/step - loss: 3.1659 - accuracy: 0.5207 - val_loss: 1.9654 - val_accuracy: 0.6003
Epoch 23/100
97/97 [==============================] - 0s 3ms/step - loss: 2.8978 - accuracy: 0.5281 - val_loss: 2.8881 - val_accuracy: 0.6028
Epoch 24/100
97/97 [==============================] - 0s 3ms/step - loss: 1.9743 - accuracy: 0.5317 - val_loss: 2.7218 - val_accuracy: 0.4670
Epoch 25/100
97/97 [==============================] - 0s 3ms/step - loss: 1.9868 - accuracy: 0.5466 - val_loss: 1.4759 - val_accuracy: 0.6080
Epoch 26/100
97/97 [==============================] - 0s 3ms/step - loss: 2.1306 - accuracy: 0.5139 - val_loss: 2.8241 - val_accuracy: 0.5485
Epoch 27/100
97/97 [==============================] - 0s 3ms/step - loss: 1.8679 - accuracy: 0.5566 - val_loss: 1.4189 - val_accuracy: 0.6235
Epoch 28/100
97/97 [==============================] - 0s 3ms/step - loss: 1.8708 - accuracy: 0.5572 - val_loss: 1.3585 - val_accuracy: 0.5744
Epoch 29/100
97/97 [==============================] - 0s 3ms/step - loss: 1.9398 - accuracy: 0.5359 - val_loss: 2.1080 - val_accuracy: 0.4761
Epoch 30/100
97/97 [==============================] - 0s 4ms/step - loss: 1.5657 - accuracy: 0.5534 - val_loss: 2.3644 - val_accuracy: 0.5692
Epoch 31/100
97/97 [==============================] - 0s 4ms/step - loss: 1.6187 - accuracy: 0.5699 - val_loss: 1.5550 - val_accuracy: 0.4761
Epoch 32/100
97/97 [==============================] - 0s 4ms/step - loss: 1.5427 - accuracy: 0.5724 - val_loss: 1.5400 - val_accuracy: 0.5796
Epoch 33/100
97/97 [==============================] - 0s 4ms/step - loss: 1.3819 - accuracy: 0.5737 - val_loss: 1.6228 - val_accuracy: 0.5395
Epoch 34/100
97/97 [==============================] - 0s 3ms/step - loss: 1.6730 - accuracy: 0.5624 - val_loss: 1.1322 - val_accuracy: 0.6223
Epoch 35/100
97/97 [==============================] - 0s 4ms/step - loss: 1.9458 - accuracy: 0.5424 - val_loss: 1.3593 - val_accuracy: 0.5770
Epoch 36/100
97/97 [==============================] - 0s 4ms/step - loss: 1.4804 - accuracy: 0.5666 - val_loss: 1.4886 - val_accuracy: 0.6028
Epoch 37/100
97/97 [==============================] - 0s 4ms/step - loss: 1.2448 - accuracy: 0.5660 - val_loss: 1.2161 - val_accuracy: 0.6210
Epoch 38/100
97/97 [==============================] - 0s 4ms/step - loss: 1.2774 - accuracy: 0.5712 - val_loss: 1.2160 - val_accuracy: 0.6210
Epoch 39/100
97/97 [==============================] - 0s 4ms/step - loss: 1.3744 - accuracy: 0.5627 - val_loss: 1.3203 - val_accuracy: 0.6016
Epoch 40/100
97/97 [==============================] - 0s 3ms/step - loss: 1.2661 - accuracy: 0.5692 - val_loss: 1.1533 - val_accuracy: 0.5860
Epoch 41/100
97/97 [==============================] - 0s 4ms/step - loss: 1.1259 - accuracy: 0.5844 - val_loss: 1.2255 - val_accuracy: 0.5834
Epoch 42/100
97/97 [==============================] - 0s 4ms/step - loss: 1.4111 - accuracy: 0.5611 - val_loss: 0.8890 - val_accuracy: 0.6106
Epoch 43/100
97/97 [==============================] - 0s 3ms/step - loss: 1.3419 - accuracy: 0.5754 - val_loss: 0.9240 - val_accuracy: 0.6326
Epoch 44/100
97/97 [==============================] - 0s 3ms/step - loss: 1.1648 - accuracy: 0.5828 - val_loss: 1.4882 - val_accuracy: 0.5783
Epoch 45/100
97/97 [==============================] - 0s 3ms/step - loss: 1.3254 - accuracy: 0.5647 - val_loss: 0.9702 - val_accuracy: 0.6611
Epoch 46/100
97/97 [==============================] - 0s 3ms/step - loss: 1.3007 - accuracy: 0.5724 - val_loss: 2.3793 - val_accuracy: 0.5097
Epoch 47/100
97/97 [==============================] - 0s 3ms/step - loss: 1.1896 - accuracy: 0.5724 - val_loss: 1.0248 - val_accuracy: 0.6494
Epoch 48/100
97/97 [==============================] - 0s 3ms/step - loss: 1.0402 - accuracy: 0.5760 - val_loss: 1.0811 - val_accuracy: 0.5860
Epoch 49/100
97/97 [==============================] - 0s 3ms/step - loss: 0.9903 - accuracy: 0.5986 - val_loss: 1.0567 - val_accuracy: 0.6429
Epoch 50/100
97/97 [==============================] - 0s 3ms/step - loss: 0.9955 - accuracy: 0.6038 - val_loss: 0.9345 - val_accuracy: 0.5938
Epoch 51/100
97/97 [==============================] - 0s 3ms/step - loss: 0.9832 - accuracy: 0.5944 - val_loss: 0.8727 - val_accuracy: 0.6365
Epoch 52/100
97/97 [==============================] - 0s 2ms/step - loss: 0.9670 - accuracy: 0.5964 - val_loss: 1.0271 - val_accuracy: 0.6753
Epoch 53/100
97/97 [==============================] - 0s 2ms/step - loss: 0.9831 - accuracy: 0.6100 - val_loss: 0.8869 - val_accuracy: 0.5964
Epoch 54/100
97/97 [==============================] - 0s 2ms/step - loss: 0.9587 - accuracy: 0.6058 - val_loss: 0.9911 - val_accuracy: 0.5834
Epoch 55/100
97/97 [==============================] - 0s 3ms/step - loss: 0.9350 - accuracy: 0.6006 - val_loss: 0.8270 - val_accuracy: 0.6546
Epoch 56/100
97/97 [==============================] - 0s 2ms/step - loss: 0.9208 - accuracy: 0.6038 - val_loss: 0.9222 - val_accuracy: 0.6391
Epoch 57/100
97/97 [==============================] - 0s 3ms/step - loss: 0.9433 - accuracy: 0.6171 - val_loss: 0.8687 - val_accuracy: 0.5964
Epoch 58/100
97/97 [==============================] - 0s 3ms/step - loss: 1.0001 - accuracy: 0.5864 - val_loss: 1.0084 - val_accuracy: 0.6352
Epoch 59/100
97/97 [==============================] - 0s 2ms/step - loss: 0.9788 - accuracy: 0.5980 - val_loss: 0.8108 - val_accuracy: 0.6326
Epoch 60/100
97/97 [==============================] - 0s 3ms/step - loss: 1.0054 - accuracy: 0.5766 - val_loss: 0.9573 - val_accuracy: 0.6714
Epoch 61/100
97/97 [==============================] - 0s 3ms/step - loss: 0.9645 - accuracy: 0.5902 - val_loss: 0.9058 - val_accuracy: 0.6391
Epoch 62/100
97/97 [==============================] - 0s 3ms/step - loss: 0.9146 - accuracy: 0.6103 - val_loss: 0.8307 - val_accuracy: 0.6455
Epoch 63/100
97/97 [==============================] - 0s 3ms/step - loss: 0.8843 - accuracy: 0.6216 - val_loss: 0.8667 - val_accuracy: 0.6235
Epoch 64/100
97/97 [==============================] - 0s 3ms/step - loss: 0.8999 - accuracy: 0.6151 - val_loss: 0.8184 - val_accuracy: 0.6132
Epoch 65/100
97/97 [==============================] - 0s 2ms/step - loss: 0.8855 - accuracy: 0.6129 - val_loss: 0.9012 - val_accuracy: 0.6494
Epoch 66/100
97/97 [==============================] - 0s 3ms/step - loss: 1.0046 - accuracy: 0.5876 - val_loss: 1.0146 - val_accuracy: 0.6572
Epoch 67/100
97/97 [==============================] - 0s 3ms/step - loss: 0.9347 - accuracy: 0.6132 - val_loss: 0.8614 - val_accuracy: 0.5899
Epoch 68/100
97/97 [==============================] - 0s 2ms/step - loss: 0.9268 - accuracy: 0.6161 - val_loss: 0.8274 - val_accuracy: 0.6119
Epoch 69/100
97/97 [==============================] - 0s 3ms/step - loss: 0.9056 - accuracy: 0.6045 - val_loss: 0.8748 - val_accuracy: 0.6235
Epoch 70/100
97/97 [==============================] - 0s 3ms/step - loss: 0.8976 - accuracy: 0.6180 - val_loss: 0.8260 - val_accuracy: 0.6417
Epoch 71/100
97/97 [==============================] - 0s 3ms/step - loss: 0.8892 - accuracy: 0.6300 - val_loss: 0.8628 - val_accuracy: 0.6261
Epoch 72/100
97/97 [==============================] - 0s 3ms/step - loss: 0.9001 - accuracy: 0.6219 - val_loss: 0.9163 - val_accuracy: 0.6145
Epoch 73/100
97/97 [==============================] - 0s 3ms/step - loss: 0.8935 - accuracy: 0.6242 - val_loss: 0.8017 - val_accuracy: 0.6429
Epoch 74/100
97/97 [==============================] - 0s 3ms/step - loss: 0.8787 - accuracy: 0.6271 - val_loss: 0.8381 - val_accuracy: 0.6223
Epoch 75/100
97/97 [==============================] - 0s 3ms/step - loss: 1.0469 - accuracy: 0.5802 - val_loss: 0.8802 - val_accuracy: 0.6067
Epoch 76/100
97/97 [==============================] - 0s 3ms/step - loss: 0.9413 - accuracy: 0.6048 - val_loss: 0.9119 - val_accuracy: 0.6546
Epoch 77/100
97/97 [==============================] - 0s 3ms/step - loss: 0.8953 - accuracy: 0.6125 - val_loss: 0.8875 - val_accuracy: 0.5951
Epoch 78/100
97/97 [==============================] - 0s 3ms/step - loss: 0.9064 - accuracy: 0.6132 - val_loss: 0.8891 - val_accuracy: 0.6054
Epoch 79/100
97/97 [==============================] - 0s 3ms/step - loss: 0.8888 - accuracy: 0.6119 - val_loss: 0.8775 - val_accuracy: 0.6572
Epoch 80/100
97/97 [==============================] - 0s 3ms/step - loss: 0.9538 - accuracy: 0.5993 - val_loss: 0.8540 - val_accuracy: 0.6429
Epoch 81/100
97/97 [==============================] - 0s 4ms/step - loss: 0.8945 - accuracy: 0.6193 - val_loss: 0.8523 - val_accuracy: 0.6339
Epoch 82/100
97/97 [==============================] - 0s 4ms/step - loss: 0.9099 - accuracy: 0.6080 - val_loss: 0.9599 - val_accuracy: 0.6378
Epoch 83/100
97/97 [==============================] - 0s 4ms/step - loss: 0.8925 - accuracy: 0.6071 - val_loss: 0.8532 - val_accuracy: 0.6003
Epoch 84/100
97/97 [==============================] - 0s 4ms/step - loss: 0.9002 - accuracy: 0.6009 - val_loss: 0.9185 - val_accuracy: 0.6429
Epoch 85/100
97/97 [==============================] - 0s 4ms/step - loss: 0.8944 - accuracy: 0.6177 - val_loss: 0.8561 - val_accuracy: 0.6378
Epoch 86/100
97/97 [==============================] - 0s 4ms/step - loss: 0.8842 - accuracy: 0.6080 - val_loss: 0.8490 - val_accuracy: 0.6235
Epoch 87/100
97/97 [==============================] - 0s 4ms/step - loss: 0.8892 - accuracy: 0.6180 - val_loss: 0.8570 - val_accuracy: 0.6300
Epoch 88/100
97/97 [==============================] - 0s 4ms/step - loss: 1.2151 - accuracy: 0.5530 - val_loss: 0.8824 - val_accuracy: 0.5977
Epoch 89/100
97/97 [==============================] - 0s 3ms/step - loss: 0.9251 - accuracy: 0.5970 - val_loss: 0.8963 - val_accuracy: 0.6378
Epoch 90/100
97/97 [==============================] - 0s 4ms/step - loss: 0.8954 - accuracy: 0.6193 - val_loss: 0.8290 - val_accuracy: 0.6223
Epoch 91/100
97/97 [==============================] - 0s 4ms/step - loss: 0.9143 - accuracy: 0.5993 - val_loss: 0.9637 - val_accuracy: 0.5809
Epoch 92/100
97/97 [==============================] - 0s 4ms/step - loss: 0.9064 - accuracy: 0.6129 - val_loss: 0.8247 - val_accuracy: 0.6210
Epoch 93/100
97/97 [==============================] - 0s 3ms/step - loss: 0.8751 - accuracy: 0.6261 - val_loss: 0.8849 - val_accuracy: 0.6093
Epoch 94/100
97/97 [==============================] - 0s 3ms/step - loss: 0.8913 - accuracy: 0.6113 - val_loss: 0.8725 - val_accuracy: 0.6365
Epoch 95/100
97/97 [==============================] - 0s 3ms/step - loss: 0.9092 - accuracy: 0.6051 - val_loss: 0.8382 - val_accuracy: 0.6468
Epoch 96/100
97/97 [==============================] - 0s 3ms/step - loss: 0.9333 - accuracy: 0.6016 - val_loss: 0.8641 - val_accuracy: 0.5809
Epoch 97/100
97/97 [==============================] - 0s 3ms/step - loss: 0.8874 - accuracy: 0.6109 - val_loss: 0.8607 - val_accuracy: 0.6119
Epoch 98/100
97/97 [==============================] - 0s 3ms/step - loss: 0.8653 - accuracy: 0.6261 - val_loss: 0.9171 - val_accuracy: 0.6391
Epoch 99/100
97/97 [==============================] - 0s 3ms/step - loss: 0.8675 - accuracy: 0.6210 - val_loss: 0.8416 - val_accuracy: 0.6287
Epoch 100/100
97/97 [==============================] - 0s 3ms/step - loss: 0.9138 - accuracy: 0.6051 - val_loss: 1.0105 - val_accuracy: 0.6223
25/25 [==============================] - 0s 2ms/step - loss: 1.0105 - accuracy: 0.6223
Test Loss: 1.0105271339416504
Test Accuracy: 0.6222509741783142
In [25]:
# convert y_test to binary format
y_test_classes = np.argmax(y_test, axis=1)

# predict labels for test set
y_pred = ANN_model.predict(X_test)

# convert y_pred to binary format
y_pred_classes = np.argmax(y_pred, axis=1)

# calculate accuracy score
accuracy = accuracy_score(y_test_classes, y_pred_classes)
print("Accuracy:", accuracy)

# calculate confusion matrix
conf_matrix = confusion_matrix(y_test_classes, y_pred_classes)
print(classification_report(y_test_classes, y_pred_classes))
25/25 [==============================] - 0s 1ms/step
Accuracy: 0.6222509702457956
              precision    recall  f1-score   support

           0       0.00      0.00      0.00       102
           1       0.83      0.92      0.87       249
           2       0.75      0.37      0.50       246
           3       0.43      0.91      0.58       176

    accuracy                           0.62       773
   macro avg       0.50      0.55      0.49       773
weighted avg       0.60      0.62      0.57       773

In [26]:
# plot confusion matrix
plt.figure(figsize=(8, 6))
sns.heatmap(conf_matrix, annot=True, fmt='g', cmap='Blues')
plt.xlabel('Predicted Labels')
plt.ylabel('True Labels')
plt.show()

Model 3: RandomFrorest¶


In [27]:
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report

# Load the feature data
feature_df = pd.read_csv('/content/drive/MyDrive/plant_data/selected_plant_features.csv')


# Split the data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(feature_df.drop('class', axis=1), feature_df['class'], test_size=0.2, random_state=42,shuffle="True")

# Train a random forest classifier
RF_model = RandomForestClassifier(n_estimators=100, random_state=42)
RF_model.fit(X_train, y_train)

# Predict the class labels for the test data
y_pred = RF_model.predict(X_test)

# Print the classification report
print(classification_report(y_test, y_pred))
                              precision    recall  f1-score   support

     Cercospora_disease_otsu       0.48      0.26      0.34       123
            Common_rust_otsu       0.90      0.92      0.91       230
         Healthy_leaves_otsu       0.71      0.73      0.72       228
Northern_Blight_disease_otsu       0.52      0.65      0.58       192

                    accuracy                           0.69       773
                   macro avg       0.65      0.64      0.64       773
                weighted avg       0.68      0.69      0.68       773

In [28]:
# Print the accuracy
accuracy = accuracy_score(y_test, y_pred)
print('Accuracy:', accuracy)

# Print the confusion matrix
cm = confusion_matrix(y_test, y_pred)
print(classification_report(y_test, y_pred))
Accuracy: 0.6908150064683053
                              precision    recall  f1-score   support

     Cercospora_disease_otsu       0.48      0.26      0.34       123
            Common_rust_otsu       0.90      0.92      0.91       230
         Healthy_leaves_otsu       0.71      0.73      0.72       228
Northern_Blight_disease_otsu       0.52      0.65      0.58       192

                    accuracy                           0.69       773
                   macro avg       0.65      0.64      0.64       773
                weighted avg       0.68      0.69      0.68       773

In [29]:
import seaborn as sns

# Visualize the confusion matrix
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, cmap='Blues', fmt='g')
plt.xlabel('Predicted')
plt.ylabel('True')
plt.show()

Model 4: SVM¶


In [30]:
import pandas as pd
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report

# Load the feature data
feature_df = pd.read_csv('/content/drive/MyDrive/plant_data/selected_plant_features.csv')

# Extract the selected features
# selected_features = best_features + ['class']
# feature_df = feature_df[selected_features]

# Split the data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(feature_df.drop('class', axis=1), feature_df['class'], test_size=0.2, random_state=42,shuffle="True")

# Train an SVM model
SVM_model = SVC(kernel='rbf', C=1, gamma='scale')
SVM_model.fit(X_train, y_train)

# Predict the class labels for the test data
y_pred = SVM_model.predict(X_test)

# Print the classification report
print(classification_report(y_test, y_pred))
                              precision    recall  f1-score   support

     Cercospora_disease_otsu       0.00      0.00      0.00       123
            Common_rust_otsu       0.72      0.93      0.81       230
         Healthy_leaves_otsu       0.56      0.33      0.42       228
Northern_Blight_disease_otsu       0.45      0.81      0.58       192

                    accuracy                           0.57       773
                   macro avg       0.44      0.52      0.45       773
                weighted avg       0.49      0.57      0.51       773

In [31]:
# Print the accuracy
accuracy = accuracy_score(y_test, y_pred)
print('Accuracy:', accuracy)

# Print the confusion matrix
cm = confusion_matrix(y_test, y_pred)
Accuracy: 0.574385510996119
In [32]:
import seaborn as sns

# Visualize the confusion matrix
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, cmap='Blues', fmt='g')
plt.xlabel('Predicted')
plt.ylabel('True')
plt.show()

Model 5 : Decission Tree¶


In [33]:
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix

# Load the dataset
feature_df = pd.read_csv('/content/drive/MyDrive/plant_data/selected_plant_features.csv')

# Split the data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(feature_df.drop('class', axis=1), feature_df['class'], test_size=0.2, random_state=42)

# Train a decision tree classifier
clf = DecisionTreeClassifier(random_state=42)
clf.fit(X_train, y_train)

# Make predictions on the test set
y_pred = clf.predict(X_test)

# Calculate accuracy
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy}')

# Calculate confusion matrix
cm = confusion_matrix(y_test, y_pred)
print(classification_report(y_test, y_pred))
Accuracy: 0.630012936610608
                              precision    recall  f1-score   support

     Cercospora_disease_otsu       0.36      0.31      0.33       123
            Common_rust_otsu       0.88      0.87      0.88       230
         Healthy_leaves_otsu       0.66      0.62      0.64       228
Northern_Blight_disease_otsu       0.48      0.55      0.51       192

                    accuracy                           0.63       773
                   macro avg       0.59      0.59      0.59       773
                weighted avg       0.63      0.63      0.63       773

In [34]:
import seaborn as sns

# Visualize the confusion matrix
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, cmap='Blues', fmt='g')
plt.xlabel('Predicted')
plt.ylabel('True')
plt.show()
In [ ]: